package hustlas.ball.preparse;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.regex.Pattern;

/**
 * This class represents a rule in a language
 * names of rules are denoted by <> and tokens have all caps names
 * rules are stored in a string array making it easy to parse once
 * a whole group of rules are gathered
 * This is simular to EXTRule in that it's a tuple, though this is a tuple
 * of a String and a string array
 * 
 * @author Steven
 *
 */
public class ParseRule {
	private String name;
	private String[] rules;
	private int leftRecursionIndex;
	
	public ParseRule(String name, String[] rules) {
		this.name = name;
		this.rules = rules;
		this.leftRecursionIndex = 0;
		for(String s : rules) {
			if(Pattern.compile(" ").split(s)[0].equals(name)){
				leftRecursionIndex++;
			}
		}
	}
	
	public ParseRule removeImmLeftRecursion() {
		ArrayList<String> newSelfRules = new ArrayList<String>();
		ArrayList<String> newRuleRules = new ArrayList<String>();
		String[] segmentedRule;
		String tempRule = new String();
		String newName = name.substring(0,name.length() - 1) + "'>";

		newSelfRules.addAll(Arrays.asList(rules));
		
		if(leftRecursionIndex == 0) {
			return this;
		}
		else {
			for(String s : rules) {
				segmentedRule = Pattern.compile(" ").split(s);
				tempRule = "";
				if(segmentedRule[0].equals(name)) {
					for(int i = 1; i < segmentedRule.length; i++) {
						tempRule += segmentedRule[i] + " ";
					}
					tempRule += newName;
					newRuleRules.add(tempRule);
					newSelfRules.remove(s);
				}
				
			}
			newRuleRules.add("\u03F5");
		}
		for(int i = 0; i < newSelfRules.size(); i++) {
			newSelfRules.set(i,newSelfRules.get(i) + " " + newName);
		}
		segmentedRule = new String[newSelfRules.size()];
		newSelfRules.toArray(segmentedRule);
		this.rules = segmentedRule;
		
		segmentedRule = new String[newRuleRules.size()];
		newRuleRules.toArray(segmentedRule);
		return new ParseRule(newName,segmentedRule);
	}
	
	public void refactorRules(String[] newRules) {
		this.rules = newRules;
		for(String s : rules) {
			if(Pattern.compile(" ").split(s)[0].equals(name)){
				leftRecursionIndex++;
			}
		}
		
	}
	public String getName() {
		return name;
	}
	
	public String[] getRules() {
		return rules;
	}
	
	public int getLeftRecursionIndex() {
		return leftRecursionIndex;
	}
	
	@Override
	public boolean equals(Object compare) {
		
		return compare instanceof ParseRule && this.name.equals(((ParseRule)compare).getName()) && this.rules.equals(((ParseRule)compare).getRules());
	}
}
